// 问题：MyPromise不支持then()的链式调用
// 思考：如何让then()方法支持链式调用？

// 解决：then 方法要链式调用那么就需要返回一个 Promise 对象
// 1. 在 then() 执行时就创建一个新的 MyPromise， 创建完成立即 return，保证下一个 then() 的调用不报错
    //  ---> 问题：报错消除，但第二个 then() 没有打印
// 2. 在 status 更改为完成或失败时，将打印结果 resolve(xxx) 给下一个 then()，这样就完成了链式调用的打印了
// 3. 如果外部调用在 then() 内创建了一个新的 MyPromise 并返回，那么外部调用 resolve() 时
//      --- 内部实现需要拿到外部返回的这个 MyPromise，并在内部实现中调用它的 then()
//      --- 再将 then() 的回调函数传递到外部去

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

/**
 *
 *
 * @class MyPromise
 */
class MyPromise {
    constructor(executor) {
        executor(this.resolve, this.reject)
    }
    status = PENDING

    value = null
    reason = null

    onFulfilledCallbacks = []
    onRejectedCallbacks = []

    resolve = (value) => {
        if (this.status === PENDING) {
            this.status = FULFILLED
            this.value = value
            while(this.onFulfilledCallbacks.length) {
                this.onFulfilledCallbacks.shift()(value)
            }
        }
    }
    reject = (reason) => {
        if (this.status === PENDING) {
            this.status = REJECTED
            this.reason = reason
            while(this.onRejectedCallbacks.length) {
                this.onRejectedCallbacks.shift()(reason)
            }
        }
    }

    then = (onFulfilled, onRejected) => {
        return new MyPromise((resolve, reject) => {
            if (this.status === FULFILLED) {    // 上一个 MyPromise 的状态为Fulfilled
                const x = onFulfilled(this.value)
                resolvePromise(x, resolve, reject)
            }
            else if (this.status === REJECTED) {
                onRejected(this.reason)
            } 
            else {
                this.onFulfilledCallbacks.push(onFulfilled)
                this.onRejectedCallbacks.push(onRejected)
            }
        })
    }
}
function resolvePromise(x, resolve, reject) {
    if (x instanceof MyPromise) {
        x.then(resolve, reject)
    } else {
        resolve(x)
    }
}

console.log(`--------------- 支持then()的链式调用 ------------------`)
// 这样返回 MyPromise 也会报错，因为同步执行的promise.then().then()，此时还没有新的MyPromise
const promise = new MyPromise((resolve, reject) => {
    resolve(`promise resolve: success`)
})
promise.then(value => {
    console.log(value)
    return 123
}).then(value => {
    console.log(value)
    return new MyPromise((resolve, reject) => {
        resolve(`other promise resolve: success`)
    })
}).then(value => {
    console.log(value)
})

console.log(`--------------- 链式调用 返回promise自己 ------------------`)
// 如果 then 方法返回的是自己的 Promise 对象，则会发生循环调用，这个时候程序会报错
// 问题： MyPromise 并没有报错，且 "promise1 resolve: success" 打印了两次

const promise1 = new MyPromise((resolve, reject) => {
    resolve(`promise1 resolve: success`)
})
promise1.then(value => {
    console.log(value)
    return promise1
}).then(value => {
    console.log(value)
    return new MyPromise((resolve, reject) => {
        resolve(`other promis1 resolve: success`)
    })
}).then(value => {
    console.log(value)
})